<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>组件基础</title>
    <script src="../vue.js"></script>
  </head>
  <body>
    <!-- 1 基本示例 -->
    <!-- 定义一个名为 button-counter 的新组件 -->
    <div id="app1">
      <button-counter></button-counter>
    </div>
    <hr />
    <!-- 2 组件的复用 -->
    <div id="app2">
      <button-counter></button-counter><br />
      <button-counter></button-counter><br />
      <button-counter></button-counter>
    </div>
    <hr />
    <!-- 2.1   data 必须是一个函数（如果 data 不是一个函数，则点击一个按钮就可能会影响到其它所有实例） -->
    <hr />
    <!-- 3 组件的组织 -->
    <hr />
    <!-- 4 通过 Prop 向子组件传递数据 -->
    <div id="app3">
      <blog-post title="my journey with vue"></blog-post>
      <blog-post title="Blogging with Vue"></blog-post>
      <blog-post title="Why Vue is so fun"></blog-post>
    </div>
    <hr />

    <div id="app4">
      <blog-post v-for="post in posts" v-bind:key='post.id' v-bind:title="post.title"></blog-post>
    </div>
    <hr />

    <!-- 5 单个根元素 -->
    <div id="app5">
      <blog-post2 v-for="post in posts" v-bind:key='post.id' v-bind:post="post"></blog-post2>
    </div>
    <hr />
    <!-- 6 监听子组件事件 -->
    <!-- 
			在我们开发 <blog-post> 组件时，它的一些功能可能要求我们和父级组件进行沟通。
			例如我们可能会引入一个辅助功能来放大博文的字号，同时让页面的其它部分保持默认的字号。
			它可以在模板中用来控制所有博文的字号：
		 -->
    <div id="app6" v-bind:style="{fontSize: postFontSize + 'em'}">
      <blog-post2 v-for="post in posts" v-bind:key="post.id" v-bind:post="post"></blog-post2>
    </div>
    <hr />
    <!-- <div id="app6">
		  <div :style="{ fontSize: postFontSize + 'em' }">
		    <blog-post2
		      v-for="post in posts"
		      v-bind:key="post.id"
		      v-bind:post="post"
		    ></blog-post2>
		  </div>
		</div> -->
    <hr />
    <!-- 现在我们在每篇博文正文之前添加一个按钮来放大字号： -->
    <div id="app7" v-bind:style="{fontSize: postFontSize + 'em'}">
      <blog-post3 v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="postFontSize += 0.1">
      </blog-post3>
    </div>
    <hr />
    <!-- 6.1   使用事件抛出一个值 -->
    <div id="app8" v-bind:style="{fontSize: postFontSize + 'em'}">
      <blog-post4 v-for="post in posts" v-bind:key="post.id" v-bind:post="post"
        v-on:enlarge-text="postFontSize += $event"></blog-post4>
    </div>
    <hr />
    <!-- 或者，如果这个事件处理函数是一个方法，那么这个值将会作为第一个参数传入这个方法： -->
    <div id="app9" v-bind:style="{fontSize: postFontSize + 'em'}">
      <blog-post4 v-for="post in posts" v-bind:key="post.id" v-bind:post="post" v-on:enlarge-text="onEnlargeText">
        <!-- v-bind:post="post" v-on:enlarge-text="onEnlargeText($event)" 这么写也行，可以省略方法参数 $event -->
        >
      </blog-post4>
    </div>
    <hr />
    <!-- 6.2   在组件上使用 v-model -->
    <div id="app10">
      <custom-input v-bind:value="searchText" v-on:input="searchText = $event"></custom-input>
      {{searchText}}
    </div>
    <hr />
    <div id="app11">
      <custom-input v-model="searchText"></custom-input>
      {{searchText}}
    </div>
    <hr />
    <!-- 7 通过插槽分发内容 -->
    <div id="app12">
      <alert-box>Something bad happened.</alert-box>
    </div>
    <hr />
    <!-- 8 动态组件 -->
    <!-- 组件会在 `currentTabComponent` 改变时改变 -->
    <div id="app13">
      <component v-bind:is="currentTabComponent"></component>
    </div>
    <hr />
    <!-- 9 解析 DOM 模板时的注意事项 -->
    <table id="app14">
      <tr>
        <blog-post-row></blog-post-row>
        test14
      </tr>
    </table>
    <hr />
    <table id="app15">
      <tr is="blog-post-row2"></tr>
    </table>
    <hr />

    <script type="text/javascript">
      // 1 基本示例
      //   定义一个名为 button-counter 的新组件
      Vue.component('button-counter', {
        data: function() {
          return {
            count: 0
          }
        },
        template: '<button v-on:click="count++">you clicked me for {{count}} times. </button>'
      })
      new Vue({
        el: '#app1'
      })
      // 2 组件的复用
      new Vue({
        el: '#app2'
      })

      // 2.1   data 必须是一个函数

      // 3 组件的组织

      // 4 通过 Prop 向子组件传递数据
      Vue.component('blog-post', {
        props: ['title'],
        template: '<h3>{{title}}</h3>'
      })
      new Vue({
        el: '#app3'
      })
      //   然而在一个典型的应用中，你可能在 data 里有一个博文的数组：
      new Vue({
        el: '#app4',
        data: {
          posts: [{
              id: 1,
              title: 'post1'
            },
            {
              id: 2,
              title: 'post2'
            },
            {
              id: 3,
              title: 'post3'
            }
          ]
        }
      })

      // 5 单个根元素
      Vue.component('blog-post2', {
        props: ['post'],
        template: `
					<div class="blog-post">
						<h3>{{post.title}}</h3>
						<div v-html="post.content"></div>
					</div>
				`
      })

      new Vue({
        el: '#app5',
        data: {
          posts: [{
              id: 1,
              title: 'post1',
              content: 'content1'
            },
            {
              id: 2,
              title: 'post2',
              content: 'content2'
            },
            {
              id: 3,
              title: 'post3',
              content: 'content3'
            }
          ]
        }
      })
      // 6 监听子组件事件
      new Vue({
        el: '#app6',
        data: {
          posts: [{
              id: 1,
              title: 'post4',
              content: 'content4'
            },
            {
              id: 2,
              title: 'post5',
              content: 'content5'
            },
            {
              id: 3,
              title: 'post6',
              content: 'content6'
            }
          ],
          postFontSize: 2
        }
      })
      //   现在我们在每篇博文正文之前添加一个按钮来放大字号：
      Vue.component('blog-post3', {
        props: ['post'],
        template: `
					<div class='blog-post'>
						<h3>{{post.title}}</h3>
						<button v-on:click='$emit("enlarge-text")'>enlarge text</button>
						<div v-html='post.content'></div>
					</div>
				`
      })
      new Vue({
        el: '#app7',
        data: {
          posts: [{
              id: 1,
              title: 'post7',
              content: 'content7'
            },
            {
              id: 2,
              title: 'post8',
              content: 'content8'
            }
          ],
          postFontSize: 1
        }
      })

      // 6.1   使用事件抛出一个值
      Vue.component('blog-post4', {
        props: ['post'],
        template: `
					<div class='blog-post'>
						<h3>{{post.title}}</h3>
						<button v-on:click='$emit("enlarge-text", 0.05)'>enlarge text</button>
						<div v-html='post.content'></div>
					</div>
				`
      })
      new Vue({
        el: '#app8',
        data: {
          posts: [{
              id: 1,
              title: 'post9',
              content: 'content9'
            },
            {
              id: 2,
              title: 'post10',
              content: 'content10'
            }
          ],
          postFontSize: 1
        }
      })

      new Vue({
        el: '#app9',
        data: {
          posts: [{
              id: 1,
              title: 'post11',
              content: 'content11'
            },
            {
              id: 2,
              title: 'post12',
              content: 'content12'
            }
          ],
          postFontSize: 1
        },
        methods: {
          onEnlargeText: function(enlargeAmount) {
            this.postFontSize += enlargeAmount
          }
        }
      })

      // 6.2   在组件上使用 v-model
      Vue.component('custom-input', {
        props: ['value'],
        template: `
					<input v-bind:value="value"
					 v-on:input="$emit('input', $event.target.value)" >
				`
      })
      new Vue({
        el: '#app10',
        data: {
          searchText: ''
        }
      })
      new Vue({
        el: '#app11',
        data: {
          searchText: ''
        }
      })
      // 7 通过插槽分发内容
      Vue.component('alert-box', {
        template: `
					<div class="demo-alert-box">
						<strong>ERROR! </strong>
						<slot></slot>
					</div>
				`
      })
      new Vue({
        el: '#app12'
      })

      // 8 动态组件
      Vue.component('home', {
        template: `
					<strong>home component</strong>
				`
      })
      Vue.component('posts', {
        template: `
					<strong>posts component</strong>
				`
      })
      Vue.component('archive', {
        template: `
					<strong>archive component</strong>
				`
      })
      var vm13 = new Vue({
        el: '#app13',
        data: {
          // 页面上的当前显示的组件变更为 home
          currentTabComponent: 'home'
        }
      })
      // 页面上的当前显示的组件变更为 posts
      vm13.currentTabComponent = 'posts'
      // 页面上的当前显示的组件变更为 archive
      vm13.currentTabComponent = 'archive'
      // 9 解析 DOM 模板时的注意事项
      Vue.component('blog-post-row', {
        template: `
					<td>test td component</td>
				`
      })
      new Vue({
        el: '#app14',
      })

      Vue.component('blog-post-row2', {
        template: `
					<div>test div component</div>
				`
      })
      new Vue({
        el: '#app15',
      })
    </script>
  </body>
</html>
